package com.mouxidea;

import java.util.Date;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.PDUv1;
import org.snmp4j.Snmp;
import org.snmp4j.TransportMapping;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.IpAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.UdpAddress;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

public class SnmpTrapSender {

	/**
	 * This methods sends the V1 trap to the Localhost in port 162
	 */
	public static void sendTrapVersion1() {
		Config config = Config.getInstance();
		
		// Sending Trap for sysLocation of RFC1213
		//public static final String Oid = ".1.3.6.1.2.1.1.8";
		final String Oid = config.getSnmpOid();

		//IP of Local Host
		//public static final String ipAddress = "127.0.0.1";
		final String ipAddress = config.getSnmpIp();

		//Ideally Port 162 should be used to send receive Trap, any other available Port can be used
		//public static final int port = 162;
		final String port = config.getSnmpPort();
		
		try {
			// Create Transport Mapping
			TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
			transport.listen();

			// Create Target
			CommunityTarget cTarget = new CommunityTarget();
			cTarget.setCommunity(new OctetString(config.getSnmpCommunity()));
			cTarget.setVersion(SnmpConstants.version1);
			cTarget.setAddress(new UdpAddress(ipAddress + "/" + port));
			cTarget.setTimeout(5000);
			cTarget.setRetries(2);

			PDUv1 pdu = new PDUv1();
			//pdu.setType(PDU.V1TRAP);
			pdu.setEnterprise(new OID(Oid));
			pdu.setGenericTrap(PDUv1.ENTERPRISE_SPECIFIC);
			pdu.setSpecificTrap(1);
			pdu.setAgentAddress(new IpAddress(ipAddress));

			// Send the PDU
			Snmp snmp = new Snmp(transport);
			System.out.println("Sending V1 Trap...");
			snmp.send(pdu, cTarget);
			snmp.close();
			System.out.println("Sending V1 Trap finished.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * This methods sends the V2 trap to the Localhost in port 162
	 */
	public static void sendTrapVersion2() {
		Config config = Config.getInstance();
		
		// Sending Trap for sysLocation of RFC1213
		//public static final String Oid = ".1.3.6.1.2.1.1.8";
		final String Oid = config.getSnmpOid();

		//IP of Local Host
		//public static final String ipAddress = "127.0.0.1";
		final String ipAddress = config.getSnmpIp();

		//Ideally Port 162 should be used to send receive Trap, any other available Port can be used
		//public static final int port = 162;
		final String port = config.getSnmpPort();
		
		try {
			// Create Transport Mapping
			TransportMapping<UdpAddress> transport = new DefaultUdpTransportMapping();
			transport.listen();

			// Create Target
			CommunityTarget cTarget = new CommunityTarget();
			cTarget.setCommunity(new OctetString(config.getSnmpCommunity()));
			cTarget.setVersion(SnmpConstants.version2c);
			cTarget.setAddress(new UdpAddress(ipAddress + "/" + port));
			cTarget.setRetries(2);
			cTarget.setTimeout(5000);

			// Create PDU for V2
			PDU pdu = new PDU();

			// need to specify the system up time
			pdu.add(new VariableBinding(SnmpConstants.sysUpTime,
					new OctetString(new Date().toString())));
			pdu.add(new VariableBinding(SnmpConstants.snmpTrapOID, new OID(
					Oid)));
			pdu.add(new VariableBinding(SnmpConstants.snmpTrapAddress,
					new IpAddress(ipAddress)));

			pdu.add(new VariableBinding(new OID(Oid), new OctetString("Major")));
			//pdu.setType(PDU.NOTIFICATION);

			// Send the PDU
			Snmp snmp = new Snmp(transport);
			System.out.println("Sending V2 Trap...");
			snmp.send(pdu, cTarget);
			snmp.close();
			System.out.println("Sending V2 Trap finished.");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void sendTrap(){
		Config config = Config.getInstance();
		if (Config.SNMP_V1.equals(config.getSnmpVersion())){
			sendTrapVersion1();
		}
		else if (Config.SNMP_V2.equals(config.getSnmpVersion())){
			sendTrapVersion2();
		}
	}

}
